package com.settlement.system.service.impl;

import com.settlement.system.common.enums.AccountStatusEnum;
import com.settlement.system.common.enums.CostAllocationEnum;
import com.settlement.system.common.enums.UnificationStatusEunm;
import com.settlement.system.common.exception.ServiceException;
import com.settlement.system.common.util.SecurityUtils;
import com.settlement.system.common.util.common.DateUtil;
import com.settlement.system.common.util.common.FasUtil;
import com.settlement.system.common.util.common.SystemUserUtil;
import com.settlement.system.mapper.BaseMapper;
import com.settlement.system.mapper.TblUnificationBillDetailMapper;
import com.settlement.system.mapper.TblUnificationBillSummaryMapper;
import com.settlement.system.mapper.security.userdetails.SysUserDetails;
import com.settlement.system.model.entity.common.SystemUser;
import com.settlement.system.model.entity.common.TblReceiveRefundEditor;
import com.settlement.system.model.entity.common.TblUnificationBillSummary;
import com.settlement.system.service.ITblReceiveRefundEditorService;
import com.settlement.system.service.ITblUnificationBillSummaryService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 统一账单明细汇总 服务实现类
 * @author xiaochuan
 * @since 2021-01-20
 */
@Slf4j
@Service
public class TblUnificationBillSummaryServiceImpl extends BaseServiceImpl implements ITblUnificationBillSummaryService {

    @Resource
    private TblUnificationBillSummaryMapper tblUnificationBillSummaryMapper;

    @Resource
    private TblUnificationBillDetailMapper tblUnificationBillDetailMapper;

    @Resource
    private ITblReceiveRefundEditorService tblReceiveRefundEditorService;

    @Resource
    private ITblUnificationBillSummaryService tblUnificationBillSummaryService;

    /*@Reference(version = "${dubbo.acs.api.version}", timeout = 6000)
    private RrPushNcApi rrPushNcApi;*/

    public static final String reShareTip = "该数据已分摊，是否重新分摊？";

    @Override
    public BaseMapper init() {
        return tblUnificationBillSummaryMapper;
    }

    @Override
    public TblUnificationBillSummary getFoot(Map<String, Object> params) throws ServiceException {
        try {
            return tblUnificationBillSummaryMapper.getFoot(params);
        } catch (Exception ex) {
            log.error("获取合计异常", ex);
            throw new ServiceException("获取合计异常", ex);
        }
    }

    @Override
    public String checkBeforeDelete(List<TblUnificationBillSummary> deleteList) throws ServiceException {
        try {
            List <String>list = new ArrayList();
            deleteList.forEach(item->{
                list.add(item.getId());
            });
            Map<String,Object> params = new HashMap<>();
            String id = list.toString().replaceAll("[\\[\\]\\s]", "");
            params.put("id",id);
            FasUtil.formatInQueryCondition(params,"id");
            List<String> summayIdList = tblUnificationBillSummaryMapper.selectSummayId(params);
            String summaryId = summayIdList.toString().replaceAll("[\\[\\]\\s]", "");
            params.put("summaryId",summaryId);
            FasUtil.formatInQueryCondition(params,"summaryId");

            if(CollectionUtils.isEmpty(deleteList)){
                return "没有选中的数据,不能执行撤销操作";
            }

            Integer countNcSummary = tblUnificationBillSummaryMapper.selectCountNcSummaryByCondition(params);
            if(countNcSummary>0){
                return "选中的汇总有凭证明细生成，不能直接删除";
            }

            Integer countUsedInCost = tblUnificationBillSummaryMapper.selectCountUsedInCost(params);
            if(countUsedInCost>0){
                return "已生成费用分摊数据的明细行不允许删除！";
            }


            // 先找出本账户对应的editNo
            SysUserDetails user = SecurityUtils.getUser();;
            String username = user.getUsername();
            TblReceiveRefundEditor editor = tblReceiveRefundEditorService.getEditorByLoginName(username);

            // 当前用户不是制单人身份，提示"撤销人非制单人，故无法撤销！"
            if(editor==null){
                return "非制单人，无法删除！";
            }

            params.put("notCreateUser",username);
            if(tblUnificationBillSummaryMapper.selectByNotCreateUserAndBySummaryIdList(params) > 0){
                return "选中了制单人不是当前用户的数据,不能执行删除操作";
            }
            params.remove("notCreateUser");

            tblUnificationBillSummaryService.deleteNoNcSummaryByCondition(params);
        } catch (Exception ex) {
            throw new ServiceException("刷新异常", ex);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteNoNcSummaryByCondition(Map<String, Object> params) throws ServiceException{
        try {
            //查询出来 没有生成NC的summary_id
            List<String> summaryIds = tblUnificationBillSummaryMapper.selectNoNcSummaryByCondition(params);
            if(org.apache.commons.collections4.CollectionUtils.isEmpty(summaryIds)){
                return;
            }
            //修改UnificationBillDetail的状态从  完成推送   改为  完成匹配
            tblUnificationBillDetailMapper.updateStatusBySummaryIdList(summaryIds,
                    UnificationStatusEunm.complete_push_nc.getNo(), UnificationStatusEunm.complete_match.getNo());

            //删除 统一账单汇总表相关数据
            tblUnificationBillSummaryMapper.deleteUnificationBillSummaryBySummaryIdList(summaryIds);
            // 清空summaryId
            tblUnificationBillDetailMapper.clearSummaryIdBysummaryIdList(summaryIds);
        } catch (Exception ex){
            throw new ServiceException("deleteNoNcSummaryByCondition error",ex);
        }
    }

    /**
     * 生成NC凭证
     * @param params
     * @return
     * @throws ServiceException
     */
    @Override
    public String produceNc(Map<String, Object> params) throws ServiceException {
        try {
            // 先找出本账户对应的editNo
            SysUserDetails user = SecurityUtils.getUser();;
            String username = user.getUsername();
            TblReceiveRefundEditor editor = tblReceiveRefundEditorService.getEditorByLoginName(username);

            // 当前用户不是制单人身份，提示"撤销人非制单人，故无法撤销！"
            if(editor==null){
                return "不得生成凭证，生成人不在制单人配置表中，请维护。";
            }
            Map tempParams = new HashMap();
            tempParams.putAll(params);
            String notAccountStatus = AccountStatusEnum.T0_NOT_CREATED.getNo()+","+AccountStatusEnum.T8_PRODUCE_NC_FAILED.getNo();
            tempParams.put("notAccountStatus",notAccountStatus);
            FasUtil.formatInQueryCondition(tempParams, "notAccountStatus");
            if (tblUnificationBillSummaryMapper.selectCount(tempParams) > 0) {
                return "只有[记账状态]=未生成凭证或生成凭证失败 的数据,才能生成NC凭证明细";
            }

            tempParams = new HashMap();
            tempParams.putAll(params);
            tempParams.put("notShareOrNot", CostAllocationEnum.ShareOrNotEnum.NO.getNo());
            FasUtil.formatInQueryCondition(tempParams, "notShareOrNot");
            if (tblUnificationBillSummaryMapper.selectCount(tempParams) > 0) {
                return "只有 [是否分摊]含\"否\" 的数据,才能生成NC凭证明细";
            }

            tempParams = new HashMap();
            tempParams.putAll(params);
            //tempParams.put("shareOrNot", ShareStatusEnum.T0.getNo());
            tempParams.put("accountStatus", AccountStatusEnum.T0_NOT_CREATED.getNo()+","+AccountStatusEnum.T8_PRODUCE_NC_FAILED.getNo());
            FasUtil.formatInQueryCondition(tempParams, "accountStatus");
            // 汇总时，包括不参与记账的，生成凭证时，只处理参与记账的
            tblUnificationBillSummaryMapper.updateAccountStatus(AccountStatusEnum.T1_IS_CREATING.getNo(), user.getUsername(), tempParams);
            //params.remove("status");
            params.put("shareOrNot", CostAllocationEnum.ShareOrNotEnum.NO.getNo());
            /*rrPushNcApi.produceNc(params);*/
        } catch (Exception ex) {
            log.error("生成NC凭证异常", ex);
            throw new ServiceException("生成NC凭证异常", ex);
        }
        return null;
    }

    @Override
    public String revokeNc(Map<String, Object> params) throws ServiceException {
        try {
            // 先找出本账户对应的editNo
            SysUserDetails user = SecurityUtils.getUser();;
            String username = user.getUsername();
            TblReceiveRefundEditor editor = tblReceiveRefundEditorService.getEditorByLoginName(username);

            // 当前用户不是制单人身份，提示"撤销人非制单人，故无法撤销！"
            if(editor==null){
                return "撤销人非制单人，故无法撤销！";
            }
            String editorNo = editor.getEditorName();

            // 再看 editNo 不符合本editNo的NC凭证条数，如果大于0，那么返回
            Map tempParams = new HashMap();
            tempParams.putAll(params);
            tempParams.put("notAccountStatus",AccountStatusEnum.T2_HAS_CREATED.getNo()+","+AccountStatusEnum.T3_REVOKE_CREATED.getNo());
            FasUtil.formatInQueryCondition(tempParams, "notAccountStatus");
            Integer integer = tblUnificationBillSummaryMapper.selectCount(tempParams);
            if(integer>0){
                return " [记账状态]为\"已生成凭证\"才能操作[撤销凭证]";
            }

            tempParams = new HashMap();
            tempParams.putAll(params);
            tempParams.put("notEditorName",editorNo);
            if(tblUnificationBillSummaryMapper.selectByNotEditorName(tempParams) > 0){
                return "选中了制单人不是当前用户的数据,不能执行撤销操作";
            }

            tempParams = new HashMap();
            tempParams.putAll(params);
            //tempParams.put("shareOrNot", ShareStatusEnum.T0.getNo());
            tempParams.put("accountStatus", AccountStatusEnum.T2_HAS_CREATED.getNo());
            FasUtil.formatInQueryCondition(tempParams, "accountStatus");
            // 汇总时，包括不参与记账的，生成凭证时，只处理参与记账的
            tblUnificationBillSummaryMapper.updateAccountStatus(AccountStatusEnum.T3_REVOKE_CREATED.getNo(), user.getUsername(), tempParams);

            /*if(tblUnificationBillSummaryMapper.selectCount(params) == 0){
                return "没有选中的数据,不能执行撤销操作";
            }*/
            /*rrPushNcApi.revokeNcPlus(params);*/
        } catch (Exception ex){
            log.error("撤销NC异常", ex);
            throw new ServiceException("撤销NC异常", ex);
        }
        return null;
    }

    @Override
    public String checkBeforeCostShare(Map<String, Object> params) throws ServiceException {
        try {
            Map tempParams = new HashMap();
            String shareStatus = (String) params.get("shareStatus");
            String shareOrNot = (String) params.get("shareOrNot");
            //全部
            Integer countAll = selectCount(params);
            if(countAll==0){
                return "没有筛选到进行操作的数据";
            }

            if(StringUtils.isEmpty(shareOrNot) ||
                    shareOrNot.contains(CostAllocationEnum.ShareOrNotEnum.NO.getNo())
            ){
                //查询一下[是否分摊]为不含是的有多少
                tempParams = new HashMap();
                tempParams.putAll(params);
                tempParams.put("notShareOrNot", CostAllocationEnum.ShareOrNotEnum.YES.getNo());
                FasUtil.formatInQueryCondition(tempParams, "notShareOrNot");
                Integer countNotNeedToShare = selectCount(tempParams);
                if(countNotNeedToShare > 0){
                    return "[是否分摊]含\"是\"的数据才能进行分摊操作";
                }
            }

            List<String> accountStatusOfCostShareList = selectAccountStatusOfCostShare(params);
            if(accountStatusOfCostShareList.contains(AccountStatusEnum.T2_HAS_CREATED.getNo())){
                return "该数据已生成凭证，请撤销凭证后重试。";
            }

            List<String> shareStatusList = selectShareStatus(params);
            if(!CollectionUtils.isEmpty(shareStatusList)){
                List<String>permitShareStatusList = new ArrayList<>();
                permitShareStatusList.add(CostAllocationEnum.ShareStatusEnum.T1.getNo());
                permitShareStatusList.add(CostAllocationEnum.ShareStatusEnum.T4.getNo());
                permitShareStatusList.add(CostAllocationEnum.ShareStatusEnum.T3.getNo());
                if(shareStatusList.size()==1){
                    if(shareStatusList.contains(CostAllocationEnum.ShareStatusEnum.T2.getNo())){
                        return "[分摊状态]为\"分摊中\"，不允许重新操作分摊。";
                    }
                    if(shareStatusList.contains(CostAllocationEnum.ShareStatusEnum.T3.getNo())){
                        return reShareTip;
                    }
                }
                if(shareStatusList.size()>1){
                    return "只能选择“未分摊”/“分摊失败”或者“已分摊”的数据进行单独操作";
                }
            }



        } catch (Exception ex) {
            log.error("checkBeforeCostShare error", ex);
            throw new ServiceException("checkBeforeCostShare error", ex);
        }
        return null;
    }

    @Override
    public String costShare(Map<String, Object> params) throws ServiceException {
        try {
            SysUserDetails user = SecurityUtils.getUser();;

            String s = checkBeforeCostShare(params);
            if(StringUtils.isNotEmpty(s) && !reShareTip.equals(s)){
                return s;
            }

            if(reShareTip.equals(s)){
                params.put("redo","redo");
            }

//            Map tempParams = new HashMap();
//            tempParams.putAll(params);
//            tempParams.put("shareOrNot", CostAllocationEnum.ShareOrNotEnum.YES.getNo());
//            tempParams.put("shareStatus", CostAllocationEnum.ShareStatusEnum.T1.getNo()+","+ CostAllocationEnum.ShareStatusEnum.T4.getNo());
//            FasUtil.formatInQueryCondition(tempParams, "shareOrNot","shareStatus");
//            // 汇总时，包括不参与记账的，生成凭证时，只处理参与记账的
//            tblUnificationBillSummaryMapper.updateShareStatus(CostAllocationEnum.ShareStatusEnum.T2.getNo(), user.getUsername(), tempParams);

            params.put("updateUser",user.getUsername());
            String updateTime = DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss");
            params.put("updateTime", updateTime);
            tblUnificationBillSummaryMapper.updateUpdateUserAndTime(user.getUsername(), updateTime, params);
            params.remove("shareStatus");
            /*rrPushNcApi.costShare(params);*/
        } catch (Exception ex) {
            log.error("costShare error", ex);
            throw new ServiceException("costShare error", ex);
        }
        return null;
    }

    @Override
    public List<String> selectShareStatus(Map<String, Object> params) throws ServiceException {
        return tblUnificationBillSummaryMapper.selectShareStatus(params);
    }

    @Override
    public List<String> selectAccountStatusOfCostShare(Map<String, Object> params) throws ServiceException {
        return tblUnificationBillSummaryMapper.selectAccountStatusOfCostShare(params);
    }
}

